<template>
  <!-- 三维模型弹窗 -->
  <div class="dialog-box" v-loading="isloadModel" element-loading-text="正在加载..."
    element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
    <div class="box-content">
      <div class="content-header">
        <span>添加{{ popupItemType }}</span>
      </div>

      <div class="content-body">
        <el-form ref="modelForm" :model="loadModelForm" :rules="loadModelRules" label-width="80px">
          <el-form-item label="服务名称">
            <el-input v-model="loadModelForm.serverName" placeholder="请输入服务名称"></el-input>
          </el-form-item>

          <el-form-item label="服务地址" prop="serverUrl" class="model-server-box">
            <el-input v-model="loadModelForm.serverUrl" :placeholder="modelPlaceholder" :disabled="disabled"></el-input>
            <el-button type="info" @click="openLocalFile">本地加载</el-button>
          </el-form-item>

          <template v-if="popupItemType == '三维模型文件'">
            <div class="origin-title">
              <span>模型插入点</span>
            </div>

            <el-form-item label="经度" prop="lng">
              <el-input v-model="loadModelForm.lng" placeholder="请输入经度"></el-input>
            </el-form-item>

            <el-form-item label="纬度" prop="lat">
              <el-input v-model="loadModelForm.lat" placeholder="请输入纬度"></el-input>
            </el-form-item>

            <el-form-item label="高度" prop="height">
              <el-input v-model="loadModelForm.height" placeholder="请输入高度"></el-input>
            </el-form-item>

            <el-form-item label="缩放" prop="scale">
              <el-input v-model="loadModelForm.scale" placeholder="请输入缩放值"></el-input>
            </el-form-item>
          </template>
          <el-form-item class="submit-btn">
            <el-button @click="closeModelDialog">取消</el-button>
            <el-button type="primary" @click="clickConfirmBtn">确定</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
const fs = window.require('fs');
const { ipcRenderer } = window.require('electron');
import Model from '@/components/layoutSubassemb/js/model.js';
import { validateLng, validateLat, validateHeight, validateScale, validateServerUrl } from '@/assets/js/rules.js';
export default {
  props: {
    popupItemType: {
      type: String,
      default: '三维服务'
    },

    globalViewer: {
      type: Object,
      default: null
    }
  },

  data () {
    return {
      isloadModel: false,
      loadModelForm: {
        serverName: '',
        lng: '',
        lat: '',
        height: '1',
        scale: '1',
        serverUrl: ''
      },
      loadModelRules: {
        lng: { validator: validateLng, trigger: 'blur' },
        lat: { validator: validateLat, trigger: 'blur' },
        height: { validator: validateHeight, trigger: 'blur' },
        scale: { validator: validateScale, trigger: 'blur' },
        serverUrl: { validator: validateServerUrl, trigger: 'blur' }
      },
      modelPlaceholder: '',
      disabled: false
    };
  },

  watch: {
    popupItemType (newVal, oldVal) {
      if (newVal !== oldVal) {
        this.getPlaceholder();
      }
    }
  },

  methods: {
    // 根据服务类型返回提示字
    getPlaceholder () {
      switch (this.popupItemType) {
        case '三维模型文件':
          this.modelPlaceholder = 'glb/gltf';
          break;

        case '三维场景服务':
          this.modelPlaceholder = '三维文件';
          break;

        case '三维服务':
          this.modelPlaceholder = 'merge_tile.json/tileset.json';
          break;

        default:
          break;
      }
    },

    // 打开本地文件夹
    openLocalFile () {
      let filters = this.popupItemType == '三维模型文件' ? [{ name: 'file', extensions: ['glb', 'gltf'] }] : [{ name: 'file', extensions: ['json'] }];
      const option = {
        title: `选择${this.modelPlaceholder}`,
        filters: filters,
        buttonLabel: '确定'
      };
      ipcRenderer.send('show-open-dialog', option);
      ipcRenderer.on('show-open-dialog', (event, data) => {
        console.log('打开本地文件夹：', data);
        const { filePath } = data;
        if (!filePath) return;
        const { fileName, fileIndex, substrName } = this.getFileInfo(filePath, false);
        if (this.popupItemType == '三维服务' && fileName != 'merge_tile.json' && fileName != 'tileset.json') {
          this.$parent.message('请选择 merge_tile.json/tileset.json 文件');
          return;
        }

        this.disabled = true;
        this.loadModelForm.serverUrl = filePath;
      });
    },

    // 点击确定按钮
    clickConfirmBtn () {
      try {
        this.$refs.modelForm.validate(async (valid) => {
          if (!valid) return false;
          this.isloadModel = true;

          const parentNode = this.$parent.getCurNodeData('1-1');
          const controlItem = parentNode.control.find(e => { return (e.name == '显示'); });

          const resourceId = this.$guid();
          let serverName = '';
          let serverType = '';
          let serverUrl = this.loadModelForm.serverUrl.replace(/\s*/g, "");
          let position = null;
          let scale = null;
          let isExist = null;
          const show = controlItem.icon == '隐藏_s.png' ? false : true;
          const isFirst = this.$parent.isFirstUpdataNode();

          const fromName = this.loadModelForm.serverName.replace(/\s*/g, "");
          if (fromName) {
            serverName = fromName;
            parentNode.children.forEach(item => {
              if (item.label == fromName) {
                const labelList = parentNode.children.map(e => { return e.label; });
                serverName = this.$parent.unitListName(labelList, fromName);
              }
            });
          } else {
            serverName = `我的模型_${parentNode.children.length + 1}`;
          }

          if (this.popupItemType == '三维模型文件') {
            position = {
              lng: Number(this.loadModelForm.lng.replace(/\s*/g, "")),
              lat: Number(this.loadModelForm.lat.replace(/\s*/g, "")),
              height: Number(this.loadModelForm.height.replace(/\s*/g, ""))
            };
            for (let k in position) {
              position[k] = Number(position[k]);
            }
            scale = Number(this.loadModelForm.scale.replace(/\s*/g, ""));
          }

          let isOnLine = null;
          const regOnline = /(http|https):\/\/([\w.]+\/?)\S*/ig; // 线上地址
          const regFile = /[a-z]|[A-Z]:(\\[^\\/&?\n]+)\\?/; // 本地地址
          if (regOnline.test(serverUrl)) {
            isOnLine = true;
            isExist = await this.$parent.fileExist(serverUrl);
          } else if (regFile.test(serverUrl)) {
            isOnLine = false;
            serverUrl = serverUrl.replace(/\\/g, "\\\\");
            isExist = fs.existsSync(serverUrl);
          }
          this.isloadModel = false;

          /**
           * @param {resourceId} 标识符
           * @param {serverName} 服务名称
           * @param {serverType} 服务类型（glb、gltf、3Dtileset）
           * @param {serverUrl} 服务地址
           * @param {show} 模型显影
           * @param {position} glb、gltf 类型模型定位
           * @param {scale} glb、gltf 类型模型缩放
           * @param {isExist} 服务是否存在
           * @param {isFirst} 是否第一次加载
           * */
          const getOption = () => {
            return { resourceId, serverName, serverType, serverUrl, show, position, scale, isExist, isFirst };
          };
          const { fileName, fileIndex, substrName } = this.getFileInfo(serverUrl, isOnLine);
          console.log('获取文件信息：', this.getFileInfo(serverUrl, isOnLine));
          switch (this.popupItemType) {
            case '三维模型文件':
              const regFromGltf = /(glb|gltf)$/i;
              if (!regFromGltf.test(substrName)) {
                this.$parent.message('请选择 glb/gltf 格式文件');
                return;
              }
              serverType = substrName;
              this.loadModel(getOption());
              break;

            case '三维场景服务':
              if (fileIndex != -1) {
                this.$parent.message('请选择三维文件');
                return;
              }
              serverType = '3DTileset';
              this.loadCatalogue({ ...getOption(), isOnLine });
              break;

            case '三维服务':
              const reg3DTileset = /(merge_tile.json|tileset.json)$/i;
              if (!reg3DTileset.test(fileName)) {
                this.$parent.message('请选择 merge_tile.json/tileset.json 格式文件');
                return;
              }
              serverType = '3DTileset';
              this.loadModel(getOption());
              break;

            default:
              break;
          }
        });
      } catch (error) {
        this.isloadModel = false;
      }
    },

    // 三维场景目录
    loadCatalogue (option) {
      const { serverName, serverUrl: fileUril, show, isExist, isFirst, isOnLine } = option;
      if (!isExist) return this.$parent.message('目录不存在');
      if (isOnLine) {

      } else {
        let fileList = [];
        function readdir (path) {
          const files = fs.readdirSync(path);
          for (let i = 0; i < files.length; i++) {
            const item = files[i];
            const filePath = `${path}${"\\\\"}${item}`;
            const fileStat = fs.statSync(filePath);
            if (!fileStat.isFile()) {
              const mergeTilePath = `${filePath}${"\\\\"}merge_tile.json`;
              const isExistM = fs.existsSync(mergeTilePath);
              if (isExistM) {
                fileList.push({ serverName: item, serverType: '3DTileset', serverUrl: `${filePath}${"\\\\"}merge_tile.json` });
              } else {
                const tilesetPath = `${filePath}${"\\\\"}tileset.json`;
                const isExistT = fs.existsSync(tilesetPath);
                if (isExistT) {
                  fileList.push({ serverName: item, serverType: '3DTileset', serverUrl: tilesetPath });
                }
              }
            } else {
              const reg3DTileset = /(merge_tile.json|tileset.json)$/i;
              if (reg3DTileset.test(item)) {
                fileList.push({ serverName: `${serverName}/${item}`, serverType: '3DTileset', serverUrl: `${filePath}` });
              }
            }
          }
        };
        readdir(fileUril);
        if (!fileList.length) return this.$parent.message('文件夹为空');

        let parentNode = this.$parent.getCurNodeData('1-1');
        const labelList = fileList.map(e => { return e.serverName; });
        parentNode.children.forEach(item => {
          fileList.forEach(option => {
            if (option.serverName == item.label) {
              option.serverName = this.$parent.unitListName(labelList, item.label);
            }
          });
        });

        fileList.forEach((item) => {
          const option = {
            resourceId: this.$guid(),
            serverName: item.serverName,
            serverType: item.serverType,
            serverUrl: item.serverUrl,
            show,
            isExist,
            isFirst
          };
          this.loadModel(option);
        });
      }
    },

    loadModel (option) {
      console.log('加载三维：', option);
      this.closeModelDialog();
      const { isExist } = option;
      if (isExist) {
        this._Model.loadModel(option);
      }
      this.$emit('appendModelNode', option);
    },

    // 清除弹窗参数
    clearModelForm () {
      for (let k in this.loadModelForm) {
        this.loadModelForm[k] = '';
      }
      this.disabled = false;
    },

    // 关闭弹窗
    closeModelDialog () {
      this.clearModelForm();
      this.$emit('close');
    },

    getFileInfo (url, isOnLine) {
      const pathIndex = isOnLine ? url.lastIndexOf('\/') : url.lastIndexOf('\\');
      const fileName = url.substring(pathIndex + 1, url.length); // 文件名
      const fileIndex = fileName.lastIndexOf('.'); // 文件名 . 索引
      const substrName = fileName.substr(fileIndex + 1); // 文件格式
      return { pathIndex, fileName, fileIndex, substrName };
    },

    // 提示
    message (message = '警告', type = 'warning') {
      this.$message({
        message: message,
        type: type
      });
    },
  },

  created () {
    this.viewer = this.globalViewer || this.Global.viewer;
    this._Model = new Model({ Vm: this, viewer: this.viewer });
  },

  beforeDestroy () {
    this.isloadModel = false;
    this._Model.destroy();
    this.clearModelForm();
  }
}
</script>

<style lang="less" scoped>
/deep/.model-server-box {
  margin-bottom: 45px !important;

  .el-form-item__content {
    position: relative;

    .el-button {
      position: absolute;
      right: 0;
      top: 30px;
      display: flex;
      justify-content: center;
      align-items: center;
      width: 70px;
      height: 25px;
      padding: 0;
      margin-top: 10px;
    }
  }
}
</style>